﻿package com.agileai.miscdp.hotweb.generator.mastersub;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;

import com.agileai.miscdp.MiscdpPlugin;
import com.agileai.miscdp.hotweb.database.DBManager;
import com.agileai.miscdp.hotweb.database.SqlBuilder;
import com.agileai.miscdp.hotweb.domain.Column;
import com.agileai.miscdp.hotweb.domain.PageFormField;
import com.agileai.miscdp.hotweb.domain.mastersub.MasterSubFuncModel;
import com.agileai.miscdp.hotweb.domain.mastersub.MasterSubTableModel;
import com.agileai.miscdp.hotweb.domain.mastersub.SubTableConfig;
import com.agileai.miscdp.hotweb.domain.mastersub.SubTableInfo;
import com.agileai.miscdp.hotweb.generator.Generator;
import com.agileai.miscdp.util.MiscdpUtil;
import com.agileai.util.ListUtil;
import com.agileai.util.StringUtil;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
/**
 * SQLMap文件代码生成器
 */
public class MSSqlMapGenerator implements Generator{
	private String tableName = null;
	private String sqlMapFile = null;
    private String templateDir = null;
    private String[] colNames = null;
    private String findRecordsSql = null;
    private List<SubTableConfig> subTableConfigList = new ArrayList<SubTableConfig>();
    private MasterSubFuncModel funcModel = null;
    
    private String projectName = null;
    public MSSqlMapGenerator(String projectName){
    	this.projectName = projectName;
    }
	@SuppressWarnings("unchecked")    
	public void init(MasterSubTableModel tableModel){
    	try {
	    	DBManager dbManager = DBManager.getInstance(this.projectName);
			SqlBuilder sqlBuilder = new SqlBuilder();
			String tableName = tableModel.getTableName();
			String nameSpace = MiscdpUtil.getValidName(tableName).toLowerCase();
			tableModel.setNamespace(nameSpace);
			String[] masterPrimaryKeys = dbManager.getPrimaryKeys(tableName);
			
			HashMap<String, Column> columnMap = dbManager.getColumnMap(tableName);
			sqlBuilder.addColumnsMap(tableName,columnMap);
			
			tableModel.setInsertMasterRecordSql(sqlBuilder.insertSql(tableName, colNames));
			
			List<String> primaryKeyList = ListUtil.arrayToList(masterPrimaryKeys);
			List<String> paramFieldList = new ArrayList<String>();
			paramFieldList.addAll(primaryKeyList);
			String uniqueFieldCode = funcModel.retrieveUniqueField(funcModel.getPageFormFields());
			if (StringUtil.isNotNullNotEmpty(uniqueFieldCode)){
				paramFieldList.add(uniqueFieldCode);
			}
			String[] paramFields = paramFieldList.toArray(new String[0]);
			String getMasterRecordSql = sqlBuilder.retrieveSqlByParams(colNames,tableName,paramFields);
			tableModel.setGetMasterRecordSql(getMasterRecordSql);
			
			tableModel.setUpdateMasterRecordSql(sqlBuilder.updateSql(tableName, colNames, masterPrimaryKeys));
			tableModel.setDeleteMasterRecordSql(sqlBuilder.deleteSql(tableName, masterPrimaryKeys));
			String listSQL = MiscdpUtil.getProcessedConditionSQL(findRecordsSql);
			tableModel.setFindMasterRecordsSql(listSQL);
			
			for (int i=0;i < subTableConfigList.size();i++){
				SubTableConfig subTableConfig = this.subTableConfigList.get(i);
				tableName = subTableConfig.getTableName();
				
				HashMap<String, Column> subColumnMap = dbManager.getColumnMap(tableName);
				sqlBuilder.addColumnsMap(tableName,subColumnMap);
				
				String subTableId = subTableConfig.getSubTableId();
				String[] primaryKeys = dbManager.getPrimaryKeys(tableName);
				String foreignKey = subTableConfig.getForeignKey();
				String masterKey = masterPrimaryKeys[0];
				String[] colNames = MiscdpUtil.getColNames(dbManager, tableName);
				SubTableInfo subTableInfo = new SubTableInfo();
				subTableInfo.setEntryEdit(SubTableConfig.ENTRY_EDIT_MODE.equals(subTableConfig.getEditMode()));
				tableModel.getSubTableInfoList().add(subTableInfo);
				
				subTableInfo.setDeleteSubRecordSql(sqlBuilder.deleteSql(tableName, primaryKeys));
				subTableInfo.setDeleteSubRecordsSql(sqlBuilder.deleteByForeignKeySql(tableName, foreignKey, masterKey));
				subTableInfo.setFindSubRecordsSql(subTableConfig.getQueryListSql());
				
				if (SubTableConfig.LIST_DETAIL_MODE.equals(subTableConfig.getEditMode())){
					List<String> subPrimaryKeyList = ListUtil.arrayToList(primaryKeys);
					List<String> subParamFieldList = new ArrayList<String>();
					subParamFieldList.addAll(subPrimaryKeyList);
					List<PageFormField> paramFormFields = funcModel.getSubPboxFormFields(subTableId);
					String subUniqueFieldCode = funcModel.retrieveUniqueField(paramFormFields);
					if (StringUtil.isNotNullNotEmpty(subUniqueFieldCode)){
						subParamFieldList.add(subUniqueFieldCode);
					}
					String[] subParamFields = subParamFieldList.toArray(new String[0]);
					String getSubRecordSql = sqlBuilder.retrieveSqlByParams(colNames,tableName,subParamFields);
					subTableInfo.setGetSubRecordSql(getSubRecordSql);
				}else{
					subTableInfo.setGetSubRecordSql(sqlBuilder.retrieveSql(colNames, tableName, primaryKeys));					
				}
				subTableInfo.setInsertSubRecordSql(sqlBuilder.insertSql(tableName, colNames));
				subTableInfo.setUpdateSubRecordSql(sqlBuilder.updateSql(tableName, colNames, primaryKeys));
				subTableInfo.setSubTableId(subTableId);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
    }

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void generate() {
		try {
			String fileName = "template";
			try {
				templateDir = FileLocator.toFileURL(Platform.getBundle(MiscdpPlugin.getPluginId()).getResource(fileName)).getFile().toString();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			Configuration cfg = new Configuration();
			cfg.setDirectoryForTemplateLoading(new File(templateDir+"/mastersub"));
	        cfg.setObjectWrapper(new DefaultObjectWrapper());
	        Template temp = cfg.getTemplate("SqlMap.xml.ftl");
	        MasterSubTableModel tableModel = new MasterSubTableModel();
	        tableModel.setTableName(tableName);
	        this.init(tableModel);
	        Map root = new HashMap();
	        root.put("table",tableModel);
	        FileWriter out = new FileWriter(new File(this.sqlMapFile)); 
//	        Writer out = new OutputStreamWriter(System.out);
	        temp.process(root, out);
	        out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public void setSqlMapFile(String sqlMapFile) {
		this.sqlMapFile = sqlMapFile;
	}

	public void setColNames(String[] colNames) {
		this.colNames = colNames;
	}

	public void setFindRecordsSql(String findRecordsSql) {
		this.findRecordsSql = findRecordsSql;
	}

	public List<SubTableConfig> getSubTableConfigList() {
		return subTableConfigList;
	}

	public void setSubTableConfigList(List<SubTableConfig> subTableConfigList) {
		this.subTableConfigList = subTableConfigList;
	}

	public void setFuncModel(MasterSubFuncModel funcModel) {
		this.funcModel = funcModel;
	}
}
